<?php

/**
 * 操作日志控制器
 * RESTful API 实现系统操作日志管理
 * 实现全覆盖跟踪和日志管理功能
 */

declare(strict_types=1);

namespace app\controller\home;

use app\BaseController;
use think\facade\Db;
use think\facade\Request;
use app\common\DataPermissionHelper;

class Log extends BaseController
{
    /**
     * 获取操作日志列表
     * GET /api/home/log/list
     */
    public function list()
    {
        try {
            $param = Request::param();
            $page = (int)($param['page'] ?? 1);
            $limit = (int)($param['limit'] ?? 20);
            $keywords = trim($param['keywords'] ?? '');
            $action = trim($param['action'] ?? '');
            $uid = (int)($param['uid'] ?? 0);
            $startTime = trim($param['start_time'] ?? '');
            $endTime = trim($param['end_time'] ?? '');

            // 权限检查：只有超级管理员才能查看所有日志
            if (!$this->checkSuperAdmin()) {
                return $this->error('无权限查看操作日志', 403);
            }

            // 构建查询条件
            $where = [];

            // 关键词搜索（用户名、操作对象、IP地址）
            if (!empty($keywords)) {
                $where[] = ['u.name|a.subject|a.ip', 'like', '%' . $keywords . '%'];
            }

            // 操作类型筛选
            if (!empty($action)) {
                $where[] = ['a.action', '=', $action];
            }

            // 用户筛选
            if ($uid > 0) {
                $where[] = ['a.uid', '=', $uid];
            }

            // 时间范围筛选
            if (!empty($startTime)) {
                $where[] = ['a.create_time', '>=', strtotime($startTime)];
            }
            if (!empty($endTime)) {
                $where[] = ['a.create_time', '<=', strtotime($endTime . ' 23:59:59')];
            }

            // 查询日志列表
            $query = Db::name('admin_log')
                ->field('a.*, u.name as user_name, u.username, d.title as dept_name')
                ->alias('a')
                ->leftJoin('admin u', 'a.uid = u.id')
                ->leftJoin('department d', 'u.did = d.id')
                ->where($where)
                ->order('a.create_time desc');

            $total = $query->count();
            $logs = $query->page($page, $limit)->select()->toArray();

            // 处理数据格式
            foreach ($logs as &$log) {
                $log = $this->formatLogData($log);
            }

            // 获取操作类型配置
            $typeAction = $this->getLogTypeActions();

            return $this->paginate($logs, $total, $page, $limit, '获取操作日志列表成功', [
                'type_actions' => $typeAction
            ]);
        } catch (\Exception $e) {
            return $this->error('查询失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 格式化日志数据
     */
    private function formatLogData($log)
    {
        // 时间格式化
        $log['create_time_format'] = date('Y-m-d H:i:s', $log['create_time']);
        $log['create_date'] = date('Y-m-d', $log['create_time']);

        // 操作内容描述
        $log['content'] = ($log['user_name'] ?? '未知用户') . $log['action'] . '了' . $log['subject'];

        // 处理参数
        $paramArray = json_decode($log['param'] ?? '', true);
        if (is_array($paramArray)) {
            $paramValue = [];
            foreach ($paramArray as $key => $value) {
                if (is_array($value)) {
                    $value = implode(',', $value);
                }
                $paramValue[] = $key . ':' . $value;
            }
            $log['param_formatted'] = implode(' & ', $paramValue);
            $log['param_array'] = $paramArray;
        } else {
            $log['param_formatted'] = $paramArray ?: '-';
            $log['param_array'] = [];
        }

        // 加入其他有用信息
        $log['user_info'] = [
            'name' => $log['user_name'] ?? '未知',
            'username' => $log['username'] ?? '',
            'dept_name' => $log['dept_name'] ?? '未分配'
        ];

        return $log;
    }

    /**
     * 获取操作类型配置
     */
    private function getLogTypeActions()
    {
        // 首先尝试从配置文件获取
        $typeAction = config('log.type_action');

        // 如果配置不存在，使用默认配置
        if (empty($typeAction)) {
            $typeAction = [
                '增加' => '增加',
                '编辑' => '编辑',
                '删除' => '删除',
                '查看' => '查看',
                '登录' => '登录',
                '退出' => '退出',
                '审批' => '审批',
                '导出' => '导出',
                '导入' => '导入',
                '上传' => '上传',
                '下载' => '下载'
            ];
        }

        return $typeAction;
    }

    /**
     * 查看单个日志详情
     * GET /api/home/log/{id}
     */
    public function read()
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);

            if ($id <= 0) {
                return $this->paramError('日志ID不能为空');
            }

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('无权限查看操作日志', 403);
            }

            // 查询日志详情
            $log = Db::name('admin_log')
                ->field('a.*, u.name as user_name, u.username, u.email, d.title as dept_name')
                ->alias('a')
                ->leftJoin('admin u', 'a.uid = u.id')
                ->leftJoin('department d', 'u.did = d.id')
                ->where('a.id', $id)
                ->find();

            if (empty($log)) {
                return $this->error('日志不存在', 404);
            }

            $log = $this->formatLogData($log);

            // 获取该用户的其他相关操作
            if (!empty($log['uid'])) {
                $recentLogs = Db::name('admin_log')
                    ->field('id, action, subject, create_time')
                    ->where('uid', $log['uid'])
                    ->where('id', '<>', $id)
                    ->order('create_time desc')
                    ->limit(5)
                    ->select()
                    ->each(function ($item) {
                        $item['create_time_format'] = date('Y-m-d H:i:s', $item['create_time']);
                        return $item;
                    })
                    ->toArray();

                $log['recent_operations'] = $recentLogs;
            }

            return $this->success($log, '获取日志详情成功');
        } catch (\Exception $e) {
            return $this->error('查询失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 删除日志
     * DELETE /api/home/log/{id}
     */
    public function delete()
    {
        try {
            $param = Request::param();
            $id = (int)($param['id'] ?? 0);

            if ($id <= 0) {
                return $this->paramError('日志ID不能为空');
            }

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('只有系统超级管理员才有权限删除日志！', 403);
            }

            // 检查日志是否存在
            $log = Db::name('admin_log')->where('id', $id)->find();
            if (empty($log)) {
                return $this->error('日志不存在', 404);
            }

            // 删除日志（物理删除）
            Db::name('admin_log')->where('id', $id)->delete();

            return $this->deleted('日志删除成功');
        } catch (\Exception $e) {
            return $this->error('删除失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 批量删除日志
     * POST /api/home/log/batch-delete
     */
    public function batchDelete()
    {
        try {
            $param = Request::param();
            $ids = $param['ids'] ?? [];

            if (empty($ids) || !is_array($ids)) {
                return $this->paramError('请选择要删除的日志');
            }

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('只有系统超级管理员才有权限删除日志！', 403);
            }

            // 批量删除
            $deleteCount = Db::name('admin_log')
                ->whereIn('id', $ids)
                ->delete();

            return $this->success(['count' => $deleteCount], '成功删除' . $deleteCount . '条日志');
        } catch (\Exception $e) {
            return $this->error('批量删除失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 清空日志（保留最近N天）
     * POST /api/home/log/clear
     */
    public function clear()
    {
        try {
            $param = Request::param();
            $keepDays = (int)($param['keep_days'] ?? 30); // 默认保瘕30天

            if ($keepDays < 1) {
                return $this->paramError('保留天数不能小于1天');
            }

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('只有系统超级管理员才有权限清空日志！', 403);
            }

            // 计算截止时间
            $cutoffTime = time() - ($keepDays * 24 * 60 * 60);

            // 删除过期日志
            $deleteCount = Db::name('admin_log')
                ->where('create_time', '<', $cutoffTime)
                ->delete();

            return $this->success([
                'count' => $deleteCount,
                'keep_days' => $keepDays
            ], '成功清理' . $deleteCount . '条过期日志，保留最近' . $keepDays . '天的日志');
        } catch (\Exception $e) {
            return $this->error('清理失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 日志统计分析
     * GET /api/home/log/statistics
     */
    public function statistics()
    {
        try {
            $param = Request::param();
            $days = (int)($param['days'] ?? 30); // 默认统计30天

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('无权限查看日志统计', 403);
            }

            $startTime = time() - ($days * 24 * 60 * 60);

            // 1. 总量统计
            $totalLogs = Db::name('admin_log')
                ->where('create_time', '>=', $startTime)
                ->count();

            // 2. 操作类型统计
            $actionStats = Db::name('admin_log')
                ->field('action, COUNT(*) as count')
                ->where('create_time', '>=', $startTime)
                ->group('action')
                ->order('count desc')
                ->select()
                ->toArray();

            // 3. 用户操作统计（TOP 10）
            $userStats = Db::name('admin_log')
                ->field('a.uid, u.name, COUNT(*) as count')
                ->alias('a')
                ->leftJoin('admin u', 'a.uid = u.id')
                ->where('a.create_time', '>=', $startTime)
                ->group('a.uid')
                ->order('count desc')
                ->limit(10)
                ->select()
                ->toArray();

            // 4. 每日操作趋势（最近7天）
            $dailyStats = [];
            for ($i = 6; $i >= 0; $i--) {
                $date = date('Y-m-d', time() - ($i * 24 * 60 * 60));
                $dayStart = strtotime($date);
                $dayEnd = $dayStart + (24 * 60 * 60) - 1;

                $count = Db::name('admin_log')
                    ->where('create_time', 'between', [$dayStart, $dayEnd])
                    ->count();

                $dailyStats[] = [
                    'date' => $date,
                    'count' => $count
                ];
            }

            // 5. 最活跃时间段（按小时统计）
            $hourlyStats = Db::name('admin_log')
                ->field('HOUR(FROM_UNIXTIME(create_time)) as hour, COUNT(*) as count')
                ->where('create_time', '>=', $startTime)
                ->group('hour')
                ->order('hour asc')
                ->select()
                ->toArray();

            return $this->success([
                'total_logs' => $totalLogs,
                'action_stats' => $actionStats,
                'user_stats' => $userStats,
                'daily_stats' => $dailyStats,
                'hourly_stats' => $hourlyStats,
                'period_days' => $days
            ], '获取日志统计成功');
        } catch (\Exception $e) {
            return $this->error('统计失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 导出日志
     * POST /api/home/log/export
     */
    public function export()
    {
        try {
            $param = Request::param();
            $keywords = trim($param['keywords'] ?? '');
            $action = trim($param['action'] ?? '');
            $uid = (int)($param['uid'] ?? 0);
            $startTime = trim($param['start_time'] ?? '');
            $endTime = trim($param['end_time'] ?? '');
            $limit = (int)($param['limit'] ?? 1000); // 限制导出数量

            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('只有系统超级管理员才有权限导出日志！', 403);
            }

            // 构建查询条件
            $where = [];

            if (!empty($keywords)) {
                $where[] = ['u.name|a.subject|a.ip', 'like', '%' . $keywords . '%'];
            }

            if (!empty($action)) {
                $where[] = ['a.action', '=', $action];
            }

            if ($uid > 0) {
                $where[] = ['a.uid', '=', $uid];
            }

            if (!empty($startTime)) {
                $where[] = ['a.create_time', '>=', strtotime($startTime)];
            }
            if (!empty($endTime)) {
                $where[] = ['a.create_time', '<=', strtotime($endTime . ' 23:59:59')];
            }

            // 查询数据
            $logs = Db::name('admin_log')
                ->field('a.*, u.name as user_name, u.username, d.title as dept_name')
                ->alias('a')
                ->leftJoin('admin u', 'a.uid = u.id')
                ->leftJoin('department d', 'u.did = d.id')
                ->where($where)
                ->order('a.create_time desc')
                ->limit($limit)
                ->select()
                ->toArray();

            // 格式化数据供导出
            $exportData = [];
            foreach ($logs as $log) {
                $exportData[] = [
                    'ID' => $log['id'],
                    '用户名' => $log['user_name'] ?? '未知',
                    '部门' => $log['dept_name'] ?? '未分配',
                    '操作类型' => $log['action'],
                    '操作对象' => $log['subject'],
                    'IP地址' => $log['ip'],
                    'User-Agent' => $log['useragent'],
                    '操作参数' => $log['param'],
                    '操作时间' => date('Y-m-d H:i:s', $log['create_time'])
                ];
            }

            return $this->success([
                'export_data' => $exportData,
                'total_count' => count($exportData),
                'filename' => 'admin_logs_' . date('YmdHis') . '.csv'
            ], '导出数据准备完成');
        } catch (\Exception $e) {
            return $this->error('导出失败: ' . $e->getMessage(), 500);
        }
    }

    /**
     * 获取日志配置信息
     * GET /api/home/log/config
     */
    public function config()
    {
        try {
            // 权限检查
            if (!$this->checkSuperAdmin()) {
                return $this->error('无权限查看日志配置', 403);
            }

            // 获取操作类型配置
            $typeActions = $this->getLogTypeActions();

            // 获取用户列表
            $users = Db::name('admin')
                ->field('id, name, username')
                ->where('status', 1)
                ->order('id asc')
                ->select()
                ->toArray();

            // 获取日志统计信息
            $totalCount = Db::name('admin_log')->count();
            $todayCount = Db::name('admin_log')
                ->where('create_time', '>=', strtotime(date('Y-m-d')))
                ->count();

            return $this->success([
                'type_actions' => $typeActions,
                'users' => $users,
                'statistics' => [
                    'total_count' => $totalCount,
                    'today_count' => $todayCount
                ]
            ], '获取日志配置成功');
        } catch (\Exception $e) {
            return $this->error('获取配置失败: ' . $e->getMessage(), 500);
        }
    }

    // === 向后兼容方法 ===



    /**
     * 向后兼容：查看日志详情
     */
    public function view()
    {
        return $this->read();
    }

    /**
     * 向后兼容：删除日志
     */
    public function del()
    {
        return $this->delete();
    }
}
